//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using Eas.WebCrawler.Interfaces;

namespace Eas.WebCrawler.Model.Core {
    internal class BaseWebCrawlerContext : Eas.WebCrawler.Common.BaseDisposable, Eas.WebCrawler.Interfaces.WebCrawlerContext{
        private WebCrawlerSettings _Settings;
        private RequestStore _Store;
        private Eas.WebCrawler.Interfaces.WebCrawlerEvents _Events;
        private Eas.WebCrawler.Interfaces.CompletedRequestHistory _History;
        private IComparer<Eas.WebCrawler.Interfaces.Request> _Comparer;
        //le ls sf
        private Eas.WebCrawler.Interfaces.TemporaryStorageFactory _StorageFactory;
        private Eas.WebCrawler.Interfaces.LinkSelector _Selector;
        private Eas.WebCrawler.Interfaces.LinkExtractor _Extractor;


        public BaseWebCrawlerContext(WebCrawlerSettings settings, RequestStore store, Eas.WebCrawler.Interfaces.WebCrawlerEvents events) {
            _Settings = settings;
            _Store = store;
            _Events = events;
            _History = _Settings.CompletedRequestHistory;  //cache because its disposable.
            _Comparer = _Settings.RequestPriorityComparer;
            _StorageFactory = _Settings.StorageFactory;
            _Selector = _Settings.Selector;
            _Extractor = _Settings.LinkExtractor;

            RegisterComponents(
                    this.Selector,
                    this.StorageFactory,
                    this.Store,
                    this.LinkExtractor,
                    this.CompletedRequestHistory,
                    this._Settings
                );
        }

        protected override void Dispose(bool isDisposing) {
            try {
                if(_History!=null) 
                    _History.Dispose();
            }
            finally {
                base.Dispose(isDisposing);
            }
        }

        //public void Initialize() {
        //    RegisterComponents(
        //            this.Selector,
        //            this.StorageFactory,
        //            this.Store,
        //            this.LinkExtractor,
        //            this.FileNamer,
        //            this.CompletedRequestHistory
        //            this._Settings
        //        );
        //}


        #region WebCrawlerContext Members

        public Eas.WebCrawler.Interfaces.RequestStore Store {
            get { return _Store; }
        }

        public Eas.WebCrawler.Interfaces.CompletedRequestHistory CompletedRequestHistory {
            get { return _History; }
        }

        public Eas.WebCrawler.Interfaces.WebCrawlerEvents Events {
            get { return _Events; }
        }

        #endregion

        #region WebCrawlerSettings Members

        public IComparer<Eas.WebCrawler.Interfaces.Request> RequestPriorityComparer {
            get { return _Comparer; }
        }

        public Eas.WebCrawler.Interfaces.LinkExtractor LinkExtractor {
            get { return _Extractor; }
        }

        public int WorkerCount {
            get { return _Settings.WorkerCount; }
        }

        public IEnumerable<string> StartingUris {
            get { return _Settings.StartingUris; }
        }

        public Eas.WebCrawler.Interfaces.LinkSelector Selector {
            get { return _Selector; }
        }

        public Eas.WebCrawler.Interfaces.TemporaryStorageFactory StorageFactory {
            get { return _StorageFactory; }
        }

        public int SleepTimeInMilliseconds {
            get { return _Settings.SleepTimeInMilliseconds; }
        }

        public int TimeoutInMilliseconds {
            get { return _Settings.TimeoutInMilliseconds; }
        }

        #endregion

        private void RegisterComponents(params Eas.WebCrawler.Interfaces.WebCrawlerComponent[] components) {
            foreach (Eas.WebCrawler.Interfaces.WebCrawlerComponent component in components) {
                component.Initialize(this);
            }
        }
    }
}
